package com.billing.gwt.client.data;

import com.billing.gwt.client.BillingRPCService;
import com.billing.gwt.client.BillingRPCServiceAsync;
import com.billing.gwt.shared.BillingEntry;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BillingDatabase {


  /**
   * Create a remote service proxy to talk to the server-side Billing service.
   */
  private final BillingRPCServiceAsync billingService = GWT.create(BillingRPCService.class);

  /**
   * The singleton instance of the database.
   */
  private static BillingDatabase instance;

  /**
   * Get the singleton instance of the contact database.
   * 
   * @return the singleton instance
   */
  public static BillingDatabase get() {
    if (instance == null) {
      instance = new BillingDatabase();
    }
    return instance;
  }

  /**
   * The provider that holds the list of contacts in the database.
   */
  private ListDataProvider<BillingEntry> dataProvider = new ListDataProvider<BillingEntry>();

  /**
   * Construct a new contact database.
   */
  private BillingDatabase() {
    //DatabaseConstants constants = GWT.create(DatabaseConstants.class);

	loadBillingEntries();
  }
  
  
private void loadBillingEntries() {
	AsyncCallback<List<BillingEntry>> callback = new AsyncCallback<List<BillingEntry>>() {
		
		@Override
		public void onSuccess(List<BillingEntry> result) {

			final List<BillingEntry> contacts = dataProvider.getList();
		    
			contacts.addAll(result);
		}
		
		@Override
		public void onFailure(Throwable caught) {
			// TODO Auto-generated method stub
			Window.alert("Could not load the billing entries: " + caught.getMessage());
			
		}
	};
	billingService.getBillingEntries(callback);
	
}


  /**
   * Add a new contact.
   * 
   * @param contact the contact to add.
   */
  public void addContact(BillingEntry contact) {
    List<BillingEntry> contacts = dataProvider.getList();
    // Remove the contact first so we don't add a duplicate.
    contacts.remove(contact);
    contacts.add(contact);
  }

  /**
   * Add a display to the database. The current range of interest of the display
   * will be populated with data.
   * 
   * @param display a {@Link HasData}.
   */
  public void addDataDisplay(HasData<BillingEntry> display) {
    dataProvider.addDataDisplay(display);
  }

  public ListDataProvider<BillingEntry> getDataProvider() {
    return dataProvider;
  }



//  /**
//   * Query all contacts for the specified category.
//   * 
//   * @param category the category
//   * @return the list of contacts in the category
//   */
//  public List<BillingEntry> queryContactsByCategory(Category category) {
//    List<BillingEntry> matches = new ArrayList<BillingEntry>();
//    for (BillingEntry contact : dataProvider.getList()) {
//      if (contact.getCategory().equals(category.getDisplayName())) {
//        matches.add(contact);
//      }
//    }
//    return matches;
//  }

//  /**
//   * Query all contacts for the specified category that begin with the specified
//   * first name prefix.
//   * 
//   * @param category the category
//   * @param firstNamePrefix the prefix of the first name
//   * @return the list of contacts in the category
//   */
//  public List<BillingEntry> queryContactsByCategoryAndFirstName(Category category,
//      String firstNamePrefix) {
//    List<BillingEntry> matches = new ArrayList<BillingEntry>();
//    for (BillingEntry contact : dataProvider.getList()) {
//      if (contact.getCategory().equals(category.getDisplayName())) {
//        matches.add(contact);
//      }
//    }
//    return matches;
//  }


  /**
   * Refresh all displays.
   */
  public void refreshDisplays() {
    dataProvider.refresh();
  }



}
